package com.sky.aop;

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Slf4j
@Component
@Aspect
public class AutoFillCommonPropertiesAspect {
    /**
     * 切入点
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    private void pt(){}

    /**
     * 前置通知
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Before("pt()")
    public void before(JoinPoint joinPoint) throws Throwable {
        log.info("开始公共字段自动填充");
        //获取当前执行方法上数据库操作类型insert or update
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        OperationType type = autoFill.value();

        //获取当前方法操作参数--实体对象
        Object[] args = joinPoint.getArgs();
        Object employee = args[0];
        log.info("填充前的参数:{}",employee);


        //准备赋值数据
        LocalDateTime now = LocalDateTime.now();
        Long id = BaseContext.getCurrentId();

        Class<?> clazz = employee.getClass();
        //赋值
        if(type == OperationType.UPDATE){
            //通过反射过去set方法
            Method updateTime = clazz.getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method updateUser = clazz.getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
            //调用Method中的invoke执行方法赋值
            updateTime.invoke(employee,now);
            updateUser.invoke(employee,id);
        }else if(type == OperationType.INSERT){
            //通过反射过去set方法
            Method updateTime = clazz.getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method updateUser = clazz.getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
            Method createTime = clazz.getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            Method createUser = clazz.getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
            //调用Method中的invoke执行方法赋值
            updateTime.invoke(employee,now);
            updateUser.invoke(employee,id);
            createTime.invoke(employee,now);
            createUser.invoke(employee,id);
        }
        log.info("自动填充完后:{}",employee);
    }
}
















